<html>
<head><meta charset="utf-8"><title>fast-math #21690 · t-compiler · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/index.html">t-compiler</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html">fast-math #21690</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="176778318"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176778318" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alexander Droste <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176778318">(Sep 27 2019 at 19:26)</a>:</h4>
<p>Hi all!</p>
<p>I was wondering if there's any ongoing work on <code>-ffast-math</code> support in Rust?</p>
<p>This would be a great addition, as <code>fast-math</code> can lead to significant performance gains, e.g. in DSP code. In particular it is sometimes crucial to vectorize code, such as the following snippet:</p>
<div class="codehilite"><pre><span></span>pub fn sum(arr: &amp;[f32; 512]) -&gt; f32 {
    let mut result = 0.0;
    for idx in 0..arr.len() {
        result += arr[idx];
    }
    result
}
</pre></div>


<p>Being aware of <code>std::intrinsics::{fadd_fast, fdiv_fast,...}</code>, those can easily get verbose compared to single character operators (<code>+</code>,<code>-</code>,..).</p>



<a name="176790495"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176790495" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176790495">(Sep 27 2019 at 22:14)</a>:</h4>
<p>I don't think we will ever want an option exactly equivalent to C -ffast-math that combines safe and unsafe optimizations. But there's interest in providing access to faster floating-point in a smoother manner than individual intrinsics.</p>



<a name="176791940"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176791940" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176791940">(Sep 27 2019 at 22:43)</a>:</h4>
<p>I would be fine with e.g. providing other types than <code>f32</code> and <code>f64</code> (e.g. <code>r32</code> and <code>r64</code>) that would provide such faster FP. I am however against introducing global flags or changing the behavior of the existing types.</p>



<a name="176793893"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176793893" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176793893">(Sep 27 2019 at 23:19)</a>:</h4>
<p>I'm aware of that position. I personally feel there <em>should</em> be an option to change algorithms written in terms of the standard floating point types to use safe optimizations, with careful definition of "safe".</p>



<a name="176794009"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176794009" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176794009">(Sep 27 2019 at 23:21)</a>:</h4>
<div class="codehilite"><pre><span></span><span class="cp">#[cfg(feature = </span><span class="s">&quot;fast_math&quot;</span><span class="cp">)]</span><span class="w"></span>
<span class="k">type</span> <span class="nc">fp32</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">r32</span><span class="p">;</span><span class="w"></span>

<span class="cp">#[cfg(not(feature = </span><span class="s">&quot;fast_math&quot;</span><span class="cp">))]</span><span class="w"></span>
<span class="k">type</span> <span class="nc">fp32</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">f32</span><span class="p">;</span><span class="w"></span>
</pre></div>


<p>and then <code>--feature fast_math</code></p>



<a name="176794028"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176794028" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176794028">(Sep 27 2019 at 23:21)</a>:</h4>
<p>I think that satisfies "option to change algorithms"</p>



<a name="176794381"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176794381" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176794381">(Sep 27 2019 at 23:29)</a>:</h4>
<p>Not if you have to put that at the top of every file using floating point, and in every crate.</p>



<a name="176795248"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176795248" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176795248">(Sep 27 2019 at 23:42)</a>:</h4>
<p>That code only needs to be in one crate, the main work is in <code>Cargo.toml</code> instead. Cargo could also add <code>--global-feature fast_math</code> to propagate the <code>cfg</code>. Alternatively this could be built on <code>option_env!(..)</code></p>



<a name="176795656"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176795656" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176795656">(Sep 27 2019 at 23:48)</a>:</h4>
<p>I could see a global flag for <code>r32</code> to switch off the default fast-math behavior, but not a flag to switch it on for <code>f32</code></p>



<a name="176795888"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176795888" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176795888">(Sep 27 2019 at 23:50)</a>:</h4>
<p>Why does that distinction matter given that it's opt-in either way? I can see an argument for why f32 couldn't default to it and r32 could (though I don't necessarily agree with that argument), but I don't see the argument against an opt-in for f32.</p>



<a name="176796050"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176796050" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176796050">(Sep 27 2019 at 23:53)</a>:</h4>
<p>Because it becomes opt-in for the crate author, who was the one who made the assumptions, not the end user of the crate somewhere deep in the dependency graph.</p>
<p>Also, I think there should be a type which is deterministic-ish irrespective of flags and standards compliant and since <code>f32</code> is that today, it seems to me it should stay that way.</p>



<a name="176796110"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176796110" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176796110">(Sep 27 2019 at 23:53)</a>:</h4>
<p>I also don't think floating point numbers are so special that they deserve so much more attention from the language. There are other things which could get global flags.</p>



<a name="176799578"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176799578" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176799578">(Sep 28 2019 at 00:56)</a>:</h4>
<p>I think an attribute might make sense, which could then be applied crate/module/function/block level, modulo hygiene interactions with macros and such possibly.</p>



<a name="176799965"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176799965" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176799965">(Sep 28 2019 at 01:06)</a>:</h4>
<p>Scoped attributes seem like costly solutions spec-wise</p>



<a name="176800701"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176800701" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176800701">(Sep 28 2019 at 01:27)</a>:</h4>
<p>Hm, I don't see how so? Like, attributes are pretty simple I feel</p>



<a name="176800849"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176800849" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176800849">(Sep 28 2019 at 01:30)</a>:</h4>
<p>How do they interact with generic functions and inlining?<br>
They may be relatively easy to implement in a stateful compiler, but that doesn't mean it's easy to specify.<br>
Moreover, to my knowledge, we do not have any such "propagate runtime behavior" attribute at the moment, so it would "open a new axis" in the language design.</p>



<a name="176800871"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176800871" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176800871">(Sep 28 2019 at 01:31)</a>:</h4>
<p>Meanwhile, types are a known concept which are not fundamentally different and which we know how to specify</p>



<a name="176802869"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176802869" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176802869">(Sep 28 2019 at 02:24)</a>:</h4>
<p>rustc_inherit_overflow_checks :)</p>



<a name="176802871"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176802871" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176802871">(Sep 28 2019 at 02:24)</a>:</h4>
<p>but true.</p>



<a name="176802878"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176802878" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176802878">(Sep 28 2019 at 02:24)</a>:</h4>
<p>That was bound to be brought up lol :D</p>



<a name="176802901"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176802901" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176802901">(Sep 28 2019 at 02:25)</a>:</h4>
<p>But "syntactically in the attributed scope" seems feasible?</p>



<a name="176802954"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176802954" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176802954">(Sep 28 2019 at 02:27)</a>:</h4>
<p>I think it's implementable (<code>rustc_inherit_overflow_checks</code> does so) but I don't think it's a good idea</p>



<a name="176802955"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176802955" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176802955">(Sep 28 2019 at 02:27)</a>:</h4>
<p>My understanding is that fast math is purely for operators, basically - from the type system POV it's no different to adding unsafe(?) methods</p>



<a name="176803009"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803009" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803009">(Sep 28 2019 at 02:28)</a>:</h4>
<p>Is that right? Like, we could expose the relevant llvm intrinsics and people could newtype implement this today</p>



<a name="176803075"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803075" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803075">(Sep 28 2019 at 02:30)</a>:</h4>
<p>taking the expose-intrinsics route seems sensible</p>



<a name="176803076"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803076" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803076">(Sep 28 2019 at 02:30)</a>:</h4>
<p>at least as a start</p>



<a name="176803077"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803077" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803077">(Sep 28 2019 at 02:30)</a>:</h4>
<p>And <code>f32</code> isn't special cases anywhere, right? Other than having primitive syntax (1.0) for it.</p>



<a name="176803089"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803089" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803089">(Sep 28 2019 at 02:31)</a>:</h4>
<p>that probably needs to be checked to answer with authority =)</p>



<a name="176803090"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803090" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803090">(Sep 28 2019 at 02:31)</a>:</h4>
<p>but it seems likely</p>



<a name="176803091"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803091" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803091">(Sep 28 2019 at 02:31)</a>:</h4>
<p>aside from pattern matching but that's going out</p>



<a name="176803094"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803094" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803094">(Sep 28 2019 at 02:31)</a>:</h4>
<p>Right yeah</p>



<a name="176803141"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803141" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803141">(Sep 28 2019 at 02:32)</a>:</h4>
<p>Do people want this as a global switch?</p>



<a name="176803145"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803145" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803145">(Sep 28 2019 at 02:33)</a>:</h4>
<p>Like, to me that seems not great</p>



<a name="176803166"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803166" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803166">(Sep 28 2019 at 02:33)</a>:</h4>
<p>From a usability - even ignoring our desire to avoid it in the language - standpoint</p>



<a name="176803277"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803277" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803277">(Sep 28 2019 at 02:37)</a>:</h4>
<p>I believe these are the options (some mutually compatible):</p>
<ol>
<li>
<p>Global switch for <code>f32</code> [opt-in, out-out]</p>
</li>
<li>
<p>Expose LLVM intrinsics but use <code>f32</code> as types.</p>
<p>a) Newtype <code>f32</code> with those.</p>
</li>
<li>
<p>Introduce a primitive type <code>r32</code></p>
<p>a) Global switch for <code>r32</code> [opt-in, out-out]</p>
<p>b) Add ability to cargo to have <code>--global-feature fast_math</code><br>
 c) Use <code>option_env!(...)</code> instead with enhanced CTFE</p>
</li>
<li>
<p>Scoped attributes</p>
</li>
</ol>



<a name="176803321"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803321" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803321">(Sep 28 2019 at 02:38)</a>:</h4>
<p>I'm OK with 2. and 3.</p>



<a name="176803322"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176803322" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176803322">(Sep 28 2019 at 02:38)</a>:</h4>
<p>I do believe many people want 1.</p>



<a name="176819345"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176819345" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176819345">(Sep 28 2019 at 09:58)</a>:</h4>
<p><span class="user-mention" data-user-id="116122">@simulacrum</span> Clarification: this isn't just for operators, it's also for code generation between functions and similar.</p>



<a name="176819355"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176819355" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176819355">(Sep 28 2019 at 09:59)</a>:</h4>
<p>So, for instance, you could do multiple operations and not truncate/round between them.</p>



<a name="176819406"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176819406" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176819406">(Sep 28 2019 at 10:00)</a>:</h4>
<p>That isn't just about addition or multiplication (though that's important), it's also about any other floating point function.</p>



<a name="176820162"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176820162" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alexander Droste <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176820162">(Sep 28 2019 at 10:20)</a>:</h4>
<p>Thanks everyone for giving this some thought! </p>
<p>I much agree that it would be nice to scope fast-math and not have it globally enabled. </p>
<p>Looking at the options <span class="user-mention" data-user-id="126931">@centril</span>  listed:<br>
1) Nah, I agree, a global switch would most likely apply fast-math to code where not anticipated, breaking things<br>
2) Would this require casting when interacting with <code>f32</code>?<br>
3) still processing this variant :)<br>
4) As far as I can tell, I'd probably prefer this variant as it would be explicit which part of the code is using fast-math. fast-math could be seen as a property which a function or module could be designed for/robust against.</p>



<a name="176820375"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176820375" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176820375">(Sep 28 2019 at 10:25)</a>:</h4>
<p>Newtypes are not great for this. "fast/deterministic" already has problems (some discussed above; I'd also add the extra annotation burden for both library code that tries to be generic over the different types and its users) but that binary choice is an illusion. In reality there are at least four different kinds of fast-math flags (FMFs) that should be offered independently: contraction, algebraic rewrites, approximating built-in functions, existence of nans/infs/signed zeros. Many of those can usefully subdivided further (for reference, LLVM currently has 7 and would have more if not for storage space limitations).</p>
<p>So the newtyping approach leads to a combinatorial explosion of types. This can cause various problems but I am especially worried about the code size impact it has. Besides multiplying any generic code that handles float values without caring for the fast-math flags (e.g., Vec and slice methods), we'd also probably need  a massive (also generic, but massively monomorphized) matrix of operator overloads to allow some interoperability between values computed with different FMFs. And this will be imperfect, e.g. <code>if cond { /* compute f32 with some FMFs */ } else { /* compute f32 with slightly different FMFs */}</code> will need an explicit cast.</p>
<p>There's also a related problem with libms, which mostly have a monomorphic interface in terms of f32 and f64 but the optimizer should see FMFs applied to those calls (so it can perform optimizations) even if the libm never even sees the FMFs. There's no good way to expose this with intrinsics or newtypes AFAIK.</p>



<a name="176820536"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176820536" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176820536">(Sep 28 2019 at 10:30)</a>:</h4>
<p>This is not to say I endorse a special new language feature such as global or scoped (sets of) flags. Propagating through function boundaries is necessary and trying to do that with ad-hoc flags doesn't play nicely with the compilation model (and also abstraction boundaries, only <em>some</em> functions want to inherit FMFs). But if a satisfactory solution to that can be found, it would solve the problems newtypes have.</p>



<a name="176841006"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176841006" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176841006">(Sep 28 2019 at 20:46)</a>:</h4>
<blockquote>
<p>2) Would this require casting when interacting with f32?</p>
</blockquote>
<p>Since it's a newtype <code>struct R32(pub f32);</code> you'd need to wrap manually. The main benefit of a primitive would be to feel more built-in. Though maybe we should consider user defined literals...</p>
<blockquote>
<p>I'd also add the extra annotation burden for both library code that tries to be generic over the different types and its users) but that binary choice is an illusion.</p>
</blockquote>
<p>Ostensibly <code>f32</code> and <code>f64</code> already incur such a burden cause some authors would want to deal with both so it's not a novel burden but it is likely that the desire to be generic would increase. I think we can reduce that burden through <code>impl Trait</code>, <code>associated_type_defaults</code>, <code>associated_type_bounds</code>, <code>trait_aliases</code>, and so on to make the syntactic overhead substantially smaller.</p>
<blockquote>
<p>In reality there are at least four different kinds of fast-math flags (FMFs) that should be offered independently: contraction, algebraic rewrites, approximating built-in functions, existence of nans/infs/signed zeros. [...]</p>
</blockquote>
<p>That's a lot of complexity. I'm not sure all should be offered independently except as perhaps exposed intrinsics.</p>
<blockquote>
<p>So the newtyping approach leads to a combinatorial explosion of types.</p>
</blockquote>
<p>The newtype / <code>r32</code> approach is intended as a fairly blunt instrument that says "prioritize performance at the cost of standards compliance and reliability within the limits soundness provides". I'm not sure we have to provide control over every niche trough types. We could provide some global flags to tweak the semantics of <code>r32</code> if we communicate from the get-go that crate authors using these types should be ready for such semantic changes through flags.</p>



<a name="176860072"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176860072" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176860072">(Sep 29 2019 at 07:15)</a>:</h4>
<blockquote>
<blockquote>
<p>In reality there are at least four different kinds of fast-math flags (FMFs) that should be offered independently: contraction, algebraic rewrites, approximating built-in functions, existence of nans/infs/signed zeros. [...]</p>
</blockquote>
<p>That's a lot of complexity. I'm not sure all should be offered independently except as perhaps exposed intrinsics.</p>
</blockquote>
<p>I am quite sure they should. Most users will still default to enabling all or none for convenience (as they do in C and Fortran, where these distinctions exist), but greater level of control is absolutely needed sometimes -- some aspects of "fast-math" break your algorithm but others are essential for its performance. The step from "use this newtype" to "write ALL your math out as intrinsics" seems too steep to be acceptable, so I fear people will either fall back to no FMFs at all (bad since they won't get C-competitive performance) or use the blunt "fast-math" hammer and try to work around the issues it causes as they go (bad since they jeopardize their program's reliability).</p>
<p>I also don't think it is that much complexity. No matter what approach we take precisely, there will definitely be aliases for common groups of FMFs (so UX is about the same for those who don't care) and on the implementation side it's just a bitset instead of a boolean to track. Also, alternative implementations that don't care can always collapse (e.g., into a binary fast/precise) or outright ignore FMFs. Embracing finger-grained FMFs does shift the balance towards somewhat more complex ways for users to choose FMFs, but personally I think those approaches are strong candidates even with a binary switch (e.g., due to the "libm problem" I described earlier).</p>
<p>Another consideration is that fast-math is not the only "modification of float rules" knob, there's also much space to go in the opposite direction and constrain optimizations <em>more</em> to allow users to change rounding mode, inspect and modify fp exception flags, install non-default fp exception handling, and preserve NaN bit patterns. Nobody has even sketched a design of what this would look like in Rust, but since it similarly needs to affect all primitive operations and some function calls within a certain scope or program slice, it seems plausible to me we could use the same mechanism as for FMFs.</p>



<a name="176860449"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/176860449" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#176860449">(Sep 29 2019 at 07:27)</a>:</h4>
<blockquote>
<p>The newtype / <code>r32</code> approach is intended as a fairly blunt instrument that says "prioritize performance at the cost of standards compliance and reliability within the limits soundness provides". I'm not sure we have to provide control over every niche trough types. We could provide some global flags to tweak the semantics of <code>r32</code> if we communicate from the get-go that crate authors using these types should be ready for such semantic changes through flags.</p>
</blockquote>
<p>A bit tangential but global flags (as in, affecting all crates in the crate graph) would be useless IMO. The whole reason for finer-grained flags is to allow different parts of the program different sets of optimizations. If it's a whole-program switch, all code using <code>r32</code> has to be correct under the full set of FMFs, so it might as well use those and get more optimization potential. But of course, in reality library authors won't be perfect about this, so leaving this choice to the user who compiles the crate graph causes the same problems (to a lesser degree) as a global flag that changes all <code>f32</code>-using code to "fast-math mode".</p>
<p>Note that even C  and Fortran let you choose on a file-by-file bases. For contraction, there is even a pragma in the C standard (<code>#pragma STDC FP_CONTRACT &lt;on/off&gt;</code>) that allows one to choose on a statement-by-statement basis.</p>



<a name="177037774"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177037774" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177037774">(Oct 01 2019 at 09:26)</a>:</h4>
<p><span class="user-mention" data-user-id="228402">@Alexander Droste</span> as you probably already noticed that would be a new language feature and would need an RFC</p>



<a name="177038336"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177038336" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177038336">(Oct 01 2019 at 09:33)</a>:</h4>
<p>It is possible to make correct unsafe Rust code exhibit undefined behavior by changing floating point arithmetic, so solving the problem isn’t as easy as just adding compiler flags</p>



<a name="177047964"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177047964" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alexander Droste <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177047964">(Oct 01 2019 at 12:02)</a>:</h4>
<p><span class="user-mention" data-user-id="132920">@gnzlbg</span> Makes sense and thanks for the heads up.</p>



<a name="177050824"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177050824" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177050824">(Oct 01 2019 at 12:45)</a>:</h4>
<p>You can make correct unsafe code exhibit unsafe behavior by changing <em>any</em> defined feature in the language.</p>



<a name="177050881"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177050881" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177050881">(Oct 01 2019 at 12:45)</a>:</h4>
<p>Just by having a conditional testing the existing behavior and performing undefined behavior if it goes the other way.</p>



<a name="177050960"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177050960" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177050960">(Oct 01 2019 at 12:46)</a>:</h4>
<p>I don't see how that negates <span class="user-mention" data-user-id="132920">@gnzlbg</span>'s point.</p>



<a name="177051020"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051020" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051020">(Oct 01 2019 at 12:47)</a>:</h4>
<p>I don't think that, by itself, implies we can never ever change any behavior. The question is whether anyone is relying on that behavior, as well as whether that behavior was actually defined in practice or whether the documentation said one thing but the code said another.</p>



<a name="177051125"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051125" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051125">(Oct 01 2019 at 12:48)</a>:</h4>
<p>For instance, the documentation says one thing about floating point precision, but if you rely on that as an ironclad spec, you will find different behavior on 32-bit x86 (for instance).</p>



<a name="177051144"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051144" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051144">(Oct 01 2019 at 12:48)</a>:</h4>
<p>then there's a bug in 32-bit x86</p>



<a name="177051153"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051153" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051153">(Oct 01 2019 at 12:48)</a>:</h4>
<p>Indeed; we have other cases (like integer-overflow) where one can observe different behaviors based on compiler flags; but we have <em>specified</em> the range of behaviors there.</p>



<a name="177051178"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051178" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051178">(Oct 01 2019 at 12:49)</a>:</h4>
<p>In practice, it isn't actually something you can rely on.</p>



<a name="177051206"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051206" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051206">(Oct 01 2019 at 12:49)</a>:</h4>
<p>You could say there's a bug in 32-bit x86. Or you could say there's a bug in the docs.</p>



<a name="177051240"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051240" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051240">(Oct 01 2019 at 12:49)</a>:</h4>
<p>I think you'd actually be hard-pressed to find any explicitly specified behavior that is inconsistent with -ffast-math or x87 precision issues. To some degree this is annoying language lawyering but e.g. we never actually say anywhere in the reference that fp addition is correctly rounded</p>



<a name="177051257"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051257" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051257">(Oct 01 2019 at 12:50)</a>:</h4>
<p><span class="user-mention" data-user-id="239881">@Josh Triplett</span> can you be more specific about what the docs say w.r.t. floating point precision that is contradicted by 32-bit x86?</p>



<a name="177051317"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051317" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051317">(Oct 01 2019 at 12:50)</a>:</h4>
<p>(not that I doubt you; at this point I'm just curious since you seem to have something concrete in mind)</p>



<a name="177051323"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051323" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051323">(Oct 01 2019 at 12:50)</a>:</h4>
<p>I would say there's a bug in the docs, and a cautious and correct programmer would observe the actual behavior.</p>



<a name="177051420"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051420" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051420">(Oct 01 2019 at 12:51)</a>:</h4>
<p>nitpick: it's only the tier 1 i586-* target where these issues crop up, all the mainstream 32 bit x86 targets require SSE2 and thus have correctly rounded f32 and f64 arithmetic</p>



<a name="177051455"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051455" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051455">(Oct 01 2019 at 12:51)</a>:</h4>
<p>Before anyone tries to reproduce this with an <code>i686-*</code> rustc</p>



<a name="177051503"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051503" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051503">(Oct 01 2019 at 12:52)</a>:</h4>
<p>Sure. The specs don't <em>quite</em> actually say, but implicitly imply, that you won't get excess precision. Because they define the floating-point types by reference to IEEE 754, and 754 doesn't prohibit excess precision but a strict reading of 754 says you should have exactly the specified precision.</p>



<a name="177051567"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051567" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051567">(Oct 01 2019 at 12:53)</a>:</h4>
<p>And yes, sorry, i586. Though you'd get the same behavior with i686 if you actually build for a target where you can't assume SSE.</p>



<a name="177051599"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051599" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051599">(Oct 01 2019 at 12:53)</a>:</h4>
<p>(deleted)</p>



<a name="177051704"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051704" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051704">(Oct 01 2019 at 12:54)</a>:</h4>
<p>My point is, when the spec and the implementation differ, sometimes the spec is wrong, sometimes the implementation is wrong, and sometimes you could argue either case.</p>



<a name="177051744"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051744" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051744">(Oct 01 2019 at 12:55)</a>:</h4>
<p>Oh, also, since I don't see it linked anywhere in this topic thus far: <a href="https://github.com/rust-lang/rust/issues/21690" target="_blank" title="https://github.com/rust-lang/rust/issues/21690">#21690</a></p>



<a name="177051753"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051753" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051753">(Oct 01 2019 at 12:55)</a>:</h4>
<p>Sometimes the spec needs to change (if that is even possible), but such a change should be intentional and go through the regular channels (i.e. FCP / RFC / ...).</p>



<a name="177051755"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051755" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051755">(Oct 01 2019 at 12:55)</a>:</h4>
<p>and in fact maybe I'll add it to the topic</p>



<a name="177051826"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177051826" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177051826">(Oct 01 2019 at 12:56)</a>:</h4>
<p>I agree re: "sometimes the spec is wrong, sometimes the impl is wrong, sometimes you could argue either". I brought up the ambiguity of the spec under a very strict reading as more ammo  for the arguing :)</p>



<a name="177052733"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177052733" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177052733">(Oct 01 2019 at 13:06)</a>:</h4>
<p>Speaking of, it's kind of funny to me that <a href="https://github.com/rust-lang-nursery/reference/pull/607" target="_blank" title="https://github.com/rust-lang-nursery/reference/pull/607">https://github.com/rust-lang-nursery/reference/pull/607</a> is not just the only explicit definition of any fp operation's semantics but probably the only one which would explicitly contradict <code>-ffast-math</code></p>



<a name="177053010"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177053010" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177053010">(Oct 01 2019 at 13:09)</a>:</h4>
<blockquote>
<p>The step from "use this newtype" to "write ALL your math out as intrinsics" seems too steep to be acceptable, so I fear people will either fall back to no FMFs at all (bad since they won't get C-competitive performance) or use the blunt "fast-math" hammer and try to work around the issues it causes as they go (bad since they jeopardize their program's reliability).</p>
</blockquote>
<p>It seems to me a small minority of will want to use a lot of tweaks a lot of the time. If you just do it sometimes then using some intrinsics doesn't feel very onerous. Also, you can still implement your own <code>Add</code> and such impls which should make it even less onerous. Maybe user defined literals (which folks want for different things anyways, e.g. units and such) and some enhanced inference would make it feel even more first-class.</p>
<p>On the flip-side, if you provide too many of these baked into the language I think that is contributing to decision paralysis.</p>



<a name="177054938"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177054938" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177054938">(Oct 01 2019 at 13:30)</a>:</h4>
<p>I don't know how small a minority it actually would be if we provided comprehensible and convenient knobs. Contraction is widely desired (to be able to use FMA instructions), and trading accuracy of built-in functions for performance is super common in some domains such as graphics, while algebraic rewrites are more unconstrained and scary (e.g., more likely to cause numeric accuracy problems in practice) and mostly relevant for automatic vectorization. I think that -ffast-math in C is mostly a binary matter is also partially due to history and bad flag naming.</p>
<p>Decision paralysis is a real risk, but can be mitigated by presentation. I mentioned shortcuts for common options earlier, and the docs could put them front-and-center (with e.g. one sentence pointing out that more control is available and link to a document with the details). Besides, solving decision paralysis by making most options so unattractive that people never consider them isn't exactly a great solution ;-)</p>



<a name="177055205"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177055205" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177055205">(Oct 01 2019 at 13:33)</a>:</h4>
<blockquote>
<p>Besides, solving decision paralysis by making most options so unattractive that people never consider them isn't exactly a great solution ;-)</p>
</blockquote>
<p>Granted but I think "so unattractive" is rather debatable ^^ -- a newtype with a short, say 2-letter name for the constructor + <code>Add</code>&amp;-friends impls + maybe user defined literals feels attractive-ish</p>



<a name="177055464"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177055464" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177055464">(Oct 01 2019 at 13:36)</a>:</h4>
<p>I refrained from writing a whole response to that suggestion but in brief this is a significant amount of boilerplate for any one library to hand-roll. And if it gets centralized into a shared library, more generality and thus more boilerplate is needed. (And none of this does anything to address the other problems with newtypes. You didn't claim it does, but let's not forget that it's also controversial whether newtypes are a decent option no matter who writes them.)</p>



<a name="177056603"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177056603" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177056603">(Oct 01 2019 at 13:49)</a>:</h4>
<p>I think we should have a couple of types, one to opt into optimizations that increase precision or are similarly safe, and one to carefully opt into flexible precision. The precise semantics of the former should be selectable via global flags; the latter should be controlled by global flags but limitable locally. Personal opinion.</p>



<a name="177056778"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177056778" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177056778">(Oct 01 2019 at 13:51)</a>:</h4>
<p>I would call the former types <code>f32</code> and <code>f64</code> (and eventually <code>f16b</code>), and I don't know what I'd call the latter types. I absolutely understand the argument for calling the former types <code>r32</code> and <code>r64</code> instead though.</p>



<a name="177057173"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177057173" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177057173">(Oct 01 2019 at 13:56)</a>:</h4>
<blockquote>
<p>You can make correct unsafe code exhibit unsafe behavior by changing <em>any</em> defined feature in the language.</p>
</blockquote>
<p>Which is why we don’t do that?</p>



<a name="177057997"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177057997" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177057997">(Oct 01 2019 at 14:05)</a>:</h4>
<blockquote>
<p>I think we should have a couple of types, one to opt into optimizations that increase precision or are similarly safe, and one to carefully opt into flexible precision. The precise semantics of the former should be selectable via global flags; the latter should be controlled by global flags but limitable locally. Personal opinion.</p>
</blockquote>
<p>The problem is specifying which optimizations each of the types and flags allows/disallows and how to satisfy the granularity requirement of users without breaking existing code as well as how to compose these flags with existing code.</p>
<p>Those global flags can cause UB on any of your dependencies, add another couple of rows to the test matrixes that numeric crates need to cover, provide no barrier of defense for crates that are known not to work with those flags enabled, as-hoc cfg-like fixes to detect the flags and eg compile_error on them cause ecosystem splits, etc.</p>



<a name="177058338"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177058338" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177058338">(Oct 01 2019 at 14:08)</a>:</h4>
<p>IMO the assumption that the caller or the binary builder can correctly choose which optimizations are sound for all code in a binary is flawed</p>



<a name="177058359"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177058359" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> gnzlbg <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177058359">(Oct 01 2019 at 14:08)</a>:</h4>
<p>As flawed as offering a global option to make all pointers “noalias” or similar</p>



<a name="177058787"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177058787" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177058787">(Oct 01 2019 at 14:12)</a>:</h4>
<blockquote>
<blockquote>
<p>You can make correct unsafe code exhibit unsafe behavior by changing <em>any</em> defined feature in the language.</p>
</blockquote>
<p>Which is why we don’t do that?</p>
</blockquote>
<p>See above. Sometimes the spec is wrong and the implementation is correct.</p>



<a name="177059303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177059303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177059303">(Oct 01 2019 at 14:17)</a>:</h4>
<blockquote>
<p>how to satisfy the granularity requirement of users</p>
</blockquote>
<p>I would argue that to a first approximation, users don't have that fine of granularity requirements. "Exactly IEEE 754" and "feel free to make it more precise, just never less" are two obvious convergence points.</p>
<p>As I said, it's debatable which of those two types should be called <code>f32</code>/<code>f64</code>.</p>
<blockquote>
<p>provide no barrier of defense for crates that are known not to work with those flags enabled, as-hoc cfg-like fixes to detect the flags and eg compile_error on them cause ecosystem splits, etc.</p>
</blockquote>
<p>There would of course be a well-supported mechanism: use a type that guarantees IEEE 754.</p>



<a name="177060023"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177060023" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177060023">(Oct 01 2019 at 14:24)</a>:</h4>
<blockquote>
<p>I would argue that to a first approximation, users don't have that fine of granularity requirements. "Exactly IEEE 754" and "feel free to make it more precise, just never less" are two obvious convergence points.</p>
</blockquote>
<p><span class="user-mention" data-user-id="239881">@Josh Triplett</span>  I think that is a balance well struck <span aria-label="+1" class="emoji emoji-1f44d" role="img" title="+1">:+1:</span></p>



<a name="177060068"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177060068" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177060068">(Oct 01 2019 at 14:24)</a>:</h4>
<p>(I just disagree on <code>f32</code> tho as you know ^^)</p>



<a name="177060123"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177060123" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177060123">(Oct 01 2019 at 14:25)</a>:</h4>
<p>I'm aware. But I also think it's useful to get down to the smallest and most precise (heh) point of disagreement, rather than leaving that point...floating. ;)</p>



<a name="177060193"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177060193" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177060193">(Oct 01 2019 at 14:25)</a>:</h4>
<p><span aria-label="rofl" class="emoji emoji-1f923" role="img" title="rofl">:rofl:</span></p>



<a name="177060267"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177060267" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177060267">(Oct 01 2019 at 14:26)</a>:</h4>
<p>So, you would support having r32 and r64 types that defaulted to contraction and increased precision, even target-specific precision?</p>



<a name="177060293"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177060293" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177060293">(Oct 01 2019 at 14:26)</a>:</h4>
<p>You just wouldn't support making f32 and f64 those types?</p>



<a name="177060323"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177060323" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177060323">(Oct 01 2019 at 14:27)</a>:</h4>
<p>That seems right, yeah</p>



<a name="177060432"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177060432" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177060432">(Oct 01 2019 at 14:28)</a>:</h4>
<p>Would you support crate-local flags to make the f types have that behavior, and just not global flags?</p>



<a name="177060745"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177060745" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177060745">(Oct 01 2019 at 14:30)</a>:</h4>
<p>At first instance I would not. I think it would be better, due to e.g. interactions with generics and higher order functions that the <code>f*</code> types have a single canonical meaning no matter what</p>



<a name="177060839"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177060839" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177060839">(Oct 01 2019 at 14:31)</a>:</h4>
<p>Interesting. I find that a rather compelling argument against crate-local flags, though not against global flags.</p>



<a name="177060928"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177060928" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177060928">(Oct 01 2019 at 14:32)</a>:</h4>
<p>Also, would you support building in the r types so that they can have the appropriate LLVM behavior enabled for them?</p>



<a name="177060929"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177060929" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177060929">(Oct 01 2019 at 14:32)</a>:</h4>
<p>"Global" flags would be rustc command line flags and so would not be truly global (i.e., apply through the entire crate graph) due to separate compilation</p>



<a name="177060999"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177060999" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177060999">(Oct 01 2019 at 14:33)</a>:</h4>
<p><span class="user-mention" data-user-id="124289">@rkruppe</span> Something something std-aware cargo. ;)</p>



<a name="177061044"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061044" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061044">(Oct 01 2019 at 14:33)</a>:</h4>
<p>Even then someone can build one crate with one set of flags and another crate with different flags and link them</p>



<a name="177061154"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061154" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061154">(Oct 01 2019 at 14:34)</a>:</h4>
<p>We'd need a mechanism like global allocators or panic runtimes (not to be confused with panic strategy) to truly enforce "one crate graph = one semantics"</p>



<a name="177061173"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061173" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061173">(Oct 01 2019 at 14:35)</a>:</h4>
<p>Fair point.</p>



<a name="177061198"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061198" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061198">(Oct 01 2019 at 14:35)</a>:</h4>
<p>Modulo what <span class="user-mention" data-user-id="124289">@rkruppe</span>  said I'd agree with you <span class="user-mention" data-user-id="239881">@Josh Triplett</span></p>



<a name="177061254"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061254" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> centril <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061254">(Oct 01 2019 at 14:36)</a>:</h4>
<p>(but there are other arguments wrt. back compat and "undoing the expectations that crates were written with that are unrelated to separate compilation)</p>



<a name="177061371"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061371" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061371">(Oct 01 2019 at 14:37)</a>:</h4>
<p>I should also say that to a first approximation having the r types wouldn't be terrible. I'd then end up effectively telling people (with a footnote for the details) that r32 and r64 are the floating-point types and f32 and f64 are the slow floating-point types that you shouldn't use unless you have reason to know you need them.</p>



<a name="177061385"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061385" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061385">(Oct 01 2019 at 14:37)</a>:</h4>
<p>We're probably all aware but for the record: <a href="https://github.com/rust-lang/rfcs/pull/2686" target="_blank" title="https://github.com/rust-lang/rfcs/pull/2686">https://github.com/rust-lang/rfcs/pull/2686</a></p>



<a name="177061518"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061518" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061518">(Oct 01 2019 at 14:38)</a>:</h4>
<p>It would be <em>annoying</em> to go through and fix <em>everything</em> to use generics though.</p>



<a name="177061593"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061593" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061593">(Oct 01 2019 at 14:39)</a>:</h4>
<p>And any algorithm that works fine with extra precision (which is to say, just about every algorithm) should work with r32 and r64.</p>



<a name="177061599"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061599" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061599">(Oct 01 2019 at 14:39)</a>:</h4>
<blockquote>
<p>I should also say that to a first approximation having the r types wouldn't be terrible. I'd then end up effectively telling people (with a footnote for the details) that r32 and r64 are the floating-toint types and f32 and f64 are the slow floating-point types that you shouldn't use unless you have reason to know you need them.</p>
</blockquote>
<p>Well, we probably can't get around providing a third option (at least) for the parts of -ffast-math that don't fit under your definition of rN (higher precision). In particular, numerically unsafe algebraic transformations (e.g. reassociation) would not be covered by it but are often a key component of the large performance gains which motivate people to compile with -ffast-math.</p>



<a name="177061779"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061779" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061779">(Oct 01 2019 at 14:41)</a>:</h4>
<p>I don't have as much of a problem with the idea that if you want things like reassociation that lower precision you need to use special operations or a specific block.</p>



<a name="177061865"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061865" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061865">(Oct 01 2019 at 14:42)</a>:</h4>
<p>Sure.</p>



<a name="177061884"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061884" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061884">(Oct 01 2019 at 14:42)</a>:</h4>
<p>Those should <em>definitely</em> be case-by-case opt in.</p>



<a name="177061907"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177061907" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177061907">(Oct 01 2019 at 14:42)</a>:</h4>
<p>Only if they don't break your algorithm.</p>



<a name="177062052"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177062052" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177062052">(Oct 01 2019 at 14:44)</a>:</h4>
<p>But it should be easy to get FMA or multiple operations in a higher precision register with minimal effort and without rewriting any code (or at most, changing types).</p>



<a name="177062131"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177062131" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177062131">(Oct 01 2019 at 14:45)</a>:</h4>
<p>I bring it up because it's a highly related matter and ideally we'd have a coherent story for all of this rather than several things which were designed completely separately and don't fit together conceptually</p>



<a name="177062147"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177062147" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177062147">(Oct 01 2019 at 14:45)</a>:</h4>
<p>Also, there should be trivial infallible conversions via into and from to go between f and r types.</p>



<a name="177062306"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177062306" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177062306">(Oct 01 2019 at 14:47)</a>:</h4>
<p>This is not to say these things all need to use the same mechanism, but we'd often be telling people not just "these are the fast types and these are the slow ones" but also mention next that there's also &lt;whatever other fast-math-y things we add&gt;</p>



<a name="177062581"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177062581" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177062581">(Oct 01 2019 at 14:50)</a>:</h4>
<p>I understand. I get that people do want to carefully opt into "go even faster at the expense of accuracy" mode.</p>



<a name="177062623"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177062623" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177062623">(Oct 01 2019 at 14:50)</a>:</h4>
<p>And in that mode, you do need control over "how much inaccuracy".</p>



<a name="177062675"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177062675" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177062675">(Oct 01 2019 at 14:51)</a>:</h4>
<p>Unlike the r types, where it makes sense to enable all "more precision" optimisations at once.</p>



<a name="177063022"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177063022" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177063022">(Oct 01 2019 at 14:54)</a>:</h4>
<p>I actually have a soft spot for C-standard-like "contraction at the source level only" which can be deterministic/reproducible in ways other optimizations (even contraction, when the FMAs are formed by the optimizer) aren't. But yeah it's a sensible option to group them all together.</p>



<a name="177063422"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177063422" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177063422">(Oct 01 2019 at 14:59)</a>:</h4>
<p>Anyway, if we're going to end up with local controls of some of these optimizations in some form, then I do wonder whether we could use the same for "increasing precision". New types, built-in or not, have drawbacks that have been discussed extensively. Plus, to pick up your point about getting FMAs and higher precision registers without rewriting code, changing types everywhere can still be really involved -- a module level annotation is much easier.</p>



<a name="177098487"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177098487" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177098487">(Oct 01 2019 at 21:11)</a>:</h4>
<p>A module level annotation seems like the worst of both worlds to me.</p>



<a name="177098532"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177098532" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177098532">(Oct 01 2019 at 21:11)</a>:</h4>
<p>Not global, possible type system interactions/limitations...</p>



<a name="177100634"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177100634" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177100634">(Oct 01 2019 at 21:43)</a>:</h4>
<p>To your other point: I do want a coherent picture here. But I'd like the common cases to be simple.</p>



<a name="177100703"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177100703" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177100703">(Oct 01 2019 at 21:44)</a>:</h4>
<p>(And I'm much less concerned about things that would require reprogramming the floating-point unit's behavior.)</p>



<a name="177130567"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/177130567" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#177130567">(Oct 02 2019 at 08:22)</a>:</h4>
<p>I'm curious why "not global" is a drawback? The C precedent is a (translation-unit-)global flag, but if we're all in agreement that there should be <em>some</em> opt-in to the optimizations from the code author (e.g., by using a different data type) then why do we need a global(-ish) flag in addition? Why not just always apply the optimizations to the code that opts in?</p>



<a name="178752186"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/131828-t-compiler/topic/fast-math%20%2321690/near/178752186" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/131828-t-compiler/topic/fast-math.20.2321690.html#178752186">(Oct 22 2019 at 12:53)</a>:</h4>
<p>Hey participants of this thread! It looks like seem really useful information was exchanged here. I'm not quite sure what because the thread is really long and I'm trying to catch up on hundreds of messages. =) Do you think somebody could try to write a summary of what was said? (I don't expect a consensus was reached, but just outlining the major points would be amazing.) </p>
<p>I'm not 100% sure, admittedly, where to <em>push</em> such a summary. This seems like largely a lang-design thing -- I think perhaps that we could create a directory on the lang-team repo to push summaries on interesting topics that should be considered in the future. (I would happily create such a directory to house this summary).</p>
<p>cc <span class="user-mention" data-user-id="124289">@rkruppe</span> <span class="user-mention" data-user-id="126931">@centril</span> <span class="user-mention" data-user-id="239881">@Josh Triplett</span> <span class="user-mention" data-user-id="228402">@Alexander Droste</span> <span class="user-mention" data-user-id="116122">@simulacrum</span></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>